package cn.ug.mall.web.controller;

import cn.ug.bean.LoginBean;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.core.SerializeObjectError;
import cn.ug.core.login.LoginHelper;
import cn.ug.enums.OrderStatusEnum;
import cn.ug.enums.OrderTypeEnum;
import cn.ug.feign.BankCardService;
import cn.ug.feign.MemberAddressService;
import cn.ug.mall.bean.OrderBean;
import cn.ug.mall.bean.OrderExportBean;
import cn.ug.mall.mapper.entity.OtherSubmit;
import cn.ug.mall.service.OrderService;
import cn.ug.mall.web.submit.OrderSearchSubmit;
import cn.ug.mall.web.submit.OrderSubmit;
import cn.ug.member.bean.AddressBean;
import cn.ug.util.BigDecimalUtil;
import cn.ug.util.ExportExcelUtil;
import cn.ug.util.UF;
import cn.ug.web.controller.ExportExcelController;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * @author zhaohg
 * @date 2018/07/10.
 */
@RestController
@RequestMapping("/new/order")
public class OrderController {
    @Autowired
    private OrderService         orderService;
    @Autowired
    private MemberAddressService memberAddressService;
    @Autowired
    private BankCardService      bankCardService;

    @GetMapping("/successful/num")
    public SerializeObject getSuccessfulNum(String memberId) {
        return new SerializeObject(ResultType.NORMAL, "00000001", orderService.countSuccessfulNum(memberId));
    }

    @PostMapping("/read")
    public SerializeObject read(@RequestHeader String accessToken, String orderNO) {
        orderNO = UF.toString(orderNO);
        if (orderService.read(orderNO)) {
            return new SerializeObject(ResultType.NORMAL, "00000001");
        } else {
            return new SerializeObjectError("00000005");
        }
    }

    @GetMapping("/unread/num")
    public SerializeObject getUnreadNum(@RequestHeader String accessToken, int status) {
        String memberId = LoginHelper.getLoginId();
        if(StringUtils.isBlank(memberId)) {
            return new SerializeObjectError("00000102");
        }
        return new SerializeObject(ResultType.NORMAL, "00000001", orderService.countUnreadNum(memberId, status));
    }

    /**
     * 订单列表
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/list", method = GET)
    public SerializeObject findById(@RequestHeader String accessToken, OrderSearchSubmit submit) {
        return orderService.findList(submit);
    }

    /**
     * 查询订单 byId
     *
     * @param accessToken
     * @param id
     * @return
     */
    @RequestMapping(value = "/find/{id}", method = GET)
    public SerializeObject findById(@RequestHeader String accessToken, @PathVariable("id") Long id) {
        if (id > 0) {
            return orderService.findById(id);
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 关闭订单及原因
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/close", method = POST)
    public SerializeObject closeOrder(@RequestHeader String accessToken, OtherSubmit submit) {
        if (submit.getId() > 0) {
            return orderService.closeOrder(submit);
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 备注订单
     *
     * @param accessToken
     * @return
     */
    @RequestMapping(value = "/find/remark", method = GET)
    public SerializeObject findRemark(@RequestHeader String accessToken, OtherSubmit submit) {
        if (submit.getId() > 0) {
            return orderService.findRemark(submit.getId());
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 备注订单
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/remark/update", method = POST)
    public SerializeObject remarkOrder(@RequestHeader String accessToken, OtherSubmit submit) {
        if (submit.getId() > 0) {
            return orderService.remarkOrder(submit);
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 订单发货
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/delivery", method = POST)
    public SerializeObject orderDelivery(@RequestHeader String accessToken, OtherSubmit submit) {
        if (submit.getId() > 0) {
            return orderService.orderDelivery(submit);
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 订单跟踪
     */
    @RequestMapping(value = "/track", method = GET)
    public SerializeObject orderTrack(@RequestHeader String accessToken, OtherSubmit submit) {
        if (submit.getId() > 0) {
            return orderService.orderTrack(submit.getId());
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 提金/换金下单
     */
    @PostMapping
    public SerializeObject pay(String memberId, String orderId, int quantity, long skuId, String username, BigDecimal expressFee,
                               BigDecimal processCost, int orderType, int payChannel, int status, long addressId,
                               int source, BigDecimal interestNowAmount, BigDecimal principalNowAmount,
                               BigDecimal principalHistoryAmount, BigDecimal freezeAmount) {
        OrderSubmit order = new OrderSubmit();
        order.setAddressId(addressId);
        order.setUserId(memberId);
        order.setUserName(username);
        order.setExpressFee(expressFee);
        order.setProcessCost(processCost);
        order.setOrderType(orderType);
        order.setStatus(status);
        order.setSerial(orderId);
        order.setPayChannel(payChannel);
        order.setSource(source);
        order.setInterestHistoryAmount(interestNowAmount);
        order.setPrincipalNowAmount(principalNowAmount);
        order.setPrincipalHistoryAmount(principalHistoryAmount);
        order.setFreezeAmount(freezeAmount);
        return orderService.insert(order, skuId, quantity);
    }

    @PostMapping("/fail")
    public SerializeObject fail(String orderNO, String closeRemark) {
        if (orderService.failOrder(orderNO, closeRemark)) {
            return new SerializeObject(ResultType.NORMAL, "00000001");
        } else {
            return new SerializeObject(ResultType.ERROR, "00000005");
        }
    }

    @PostMapping("/succeed")
    public SerializeObject succeed(String orderNO) {
        if (orderService.succeedOrder(orderNO)) {
            return new SerializeObject(ResultType.NORMAL, "00000001");
        } else {
            return new SerializeObject(ResultType.ERROR, "00000005");
        }
    }

    @PostMapping("/handling")
    public SerializeObject handling(String orderNO) {
        if (orderService.handlingOrder(orderNO)) {
            return new SerializeObject(ResultType.NORMAL, "00000001");
        } else {
            return new SerializeObject(ResultType.ERROR, "00000005");
        }
    }

    @GetMapping("/record")
    public SerializeObject<OrderBean> getOrder(String orderNO) {
        OrderBean entity = orderService.getOrder(orderNO);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @GetMapping("/status")
    public SerializeObject getStatus(String orderNO) {
        OrderBean entity = orderService.getOrder(orderNO);
        if (entity != null) {
            if (entity.getStatus() == 3) {
                return new SerializeObject<>(ResultType.NORMAL, entity.getStatus());
            } else {
                try {
                    Thread.sleep(8000);
                    entity = orderService.getOrder(orderNO);
                    return new SerializeObject<>(ResultType.NORMAL, entity.getStatus());
                } catch (Exception e) {

                }
            }
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 订单详细 （移动端）
     *
     * @param accessToken
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = GET)
    public SerializeObject getOrderId(@RequestHeader String accessToken, @PathVariable("id") long id) {
        if (id > 0) {
            return orderService.findById(id);
        }

        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 订单详细 （移动端）
     *
     * @param accessToken
     * @param serial
     * @return
     */
    @RequestMapping(value = "/serial/{serial}", method = GET)
    public SerializeObject getOrderBySerial(@RequestHeader String accessToken, @PathVariable("serial") String serial) {
        if (StringUtils.isNotEmpty(serial)) {
            return orderService.findBySerial(serial);
        }
        return new SerializeObject(ResultType.ERROR, "00000005");
    }

    /**
     * 订单列表 （移动端）
     *
     * @param accessToken
     * @param searchSubmit
     * @return
     */
    @RequestMapping(value = "/search", method = GET)
    public SerializeObject getOrderList(@RequestHeader String accessToken, OrderSearchSubmit searchSubmit) {
        return orderService.getOrderList(searchSubmit);
    }

    /**
     * 商城支付
     */
    @PostMapping("/pay")
    public SerializeObject userGold(@RequestHeader String accessToken, String goodsInfo, long addressId, int source, Integer couponId) {
        couponId = couponId == null ? 0 : couponId;
        LoginBean loginBean = LoginHelper.getLoginBean();
        if (loginBean == null || StringUtils.isBlank(loginBean.getId())) {
            return new SerializeObjectError("00000102");
        }
        String memberId = loginBean.getId();
        String cellphone = loginBean.getLoginName();
        if (StringUtils.isBlank(goodsInfo) || addressId <= 0 || source <= 0) {
            return new SerializeObjectError("00000002");
        }
        JSONArray infos;
        try {
            infos = JSONObject.parseArray(goodsInfo);
        } catch (Exception e) {
            return new SerializeObjectError("00000002");
        }
        if (infos == null || infos.size() == 0) {
            return new SerializeObjectError("00000002");
        }
        SerializeObject<AddressBean> addressBean = memberAddressService.getAddress(addressId);
        if (null == addressBean || addressBean.getCode() != ResultType.NORMAL || null == addressBean.getData() || !StringUtils.equals(addressBean.getData().getUserId(), memberId)) {
            return new SerializeObjectError("00000002");
        }
        SerializeObject<Integer> numBean = memberAddressService.getAddressNum(memberId);
        if (numBean == null || numBean.getData() == null || numBean.getData() < 1) {
            return new SerializeObjectError("20300211");
        }
        SerializeObject serializeObject = bankCardService.validateBindBankCard(memberId);
        if (null == serializeObject || serializeObject.getCode() != ResultType.NORMAL) {
            return new SerializeObjectError("20300210");
        }
        return orderService.pay(infos, addressId, source, memberId, cellphone, couponId);
    }

    @PostMapping("/change/address")
    public SerializeObject changeAddress(@RequestHeader String accessToken, String orderNO, long addressId) {
        if (StringUtils.isBlank(orderNO) || addressId <= 0) {
            return new SerializeObjectError("00000002");
        }
        if (orderService.changeAddress(orderNO, addressId)) {
            return new SerializeObject(ResultType.NORMAL, "00000001");
        } else {
            return new SerializeObject(ResultType.ERROR, "00000005");
        }
    }

    @PostMapping("/validate")
    public SerializeObject validateOrder(String orderNO) {
        return orderService.validateOrder(orderNO);
    }

    @GetMapping("/goods/names")
    public SerializeObject<List<String>> listGoodsNames(String orderNO) {
        return new SerializeObject<>(ResultType.NORMAL, orderService.selectGoodsNames(orderNO));
    }

    /**
     * 个人商城订单记录
     *
     * @return
     */
    @RequestMapping(value = "/export", method = GET)
    public void export(HttpServletResponse response,
                       Integer status,Integer orderType,String  userName,String startTime,String endTime) {
        String[] columnNames = {"序号", "订单编号", "下单时间", "支付时间", "发货时间", "关闭时间", "用户账号","订单支付金额(元)","商品克重（克）", "订单类型","订单状态"};
        String[] columns = {"index", "serial", "exportAddTime", "exportPayTime", "exportSendTime", "exportCloseTime", "userName","money","totalGram", "mallOrderType","mallOrderStatus"};
        String fileName = "商城订单记录";
        OrderSearchSubmit submit = new OrderSearchSubmit();
        submit.setStatus(status);
        submit.setUserName(userName);
        submit.setOrderType(orderType);
        submit.setStartTime(startTime);
        submit.setEndTime(endTime);
        submit.setPageSize(Integer.MAX_VALUE);
        SerializeObject<DataTable<OrderBean>> serializeObject = orderService.findList(submit);

        ExportExcelController<OrderExportBean> export = new ExportExcelController<>();
        export.exportExcel(fileName, fileName, columnNames, columns,
                wrapPutGoldBeanData(serializeObject.getData().getDataList()), response, ExportExcelUtil.EXCEL_FILE_2003);
    }

    private List<OrderExportBean> wrapPutGoldBeanData(List<OrderBean> list) {
        int index = 1;
        List<OrderExportBean> orderExportBeanList = new ArrayList<>();
        SimpleDateFormat df_24=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (!CollectionUtils.isEmpty(list)){
            for (OrderBean orderBean : list) {
                OrderExportBean orderExportBean = new OrderExportBean();
                BeanUtils.copyProperties(orderBean,orderExportBean);
                orderExportBean.setIndex(index++);
                orderExportBean.setMoney(BigDecimalUtil.to2Point(orderBean.getMoney()));
                orderExportBean.setMallOrderStatus(OrderStatusEnum.getByCode(orderBean.getStatus()).getName());
                orderExportBean.setMallOrderType(OrderTypeEnum.getByCode(orderBean.getOrderType()).getName());
                if (orderBean.getAddTime()!=null){
                    orderExportBean.setExportAddTime(df_24.format(orderBean.getAddTime()));
                }
                if (orderBean.getPayTime()!=null){
                    orderExportBean.setExportPayTime(df_24.format(orderBean.getPayTime()));
                }
                if (orderBean.getSendTime()!=null){
                    orderExportBean.setExportSendTime(df_24.format(orderBean.getSendTime()));
                }
                if (orderBean.getCloseTime()!=null){
                    orderExportBean.setExportCloseTime(df_24.format(orderBean.getCloseTime()));
                }
                orderExportBeanList.add(orderExportBean);
            }
        }
        return orderExportBeanList;
    }
}
